package com.tengju.support.domain.model.rule;

import lombok.NoArgsConstructor;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;

@NoArgsConstructor
public class MathCondition extends Condition{

    List<String> factors;

    Operation operation;

    String field;

    public MathCondition(String field, List<String> factors, Operation operation) {
        this.field = field;
        this.factors = factors;
        this.operation = operation;
    }

    public List<String> getFactors() {
        return factors;
    }

    public Operation getOperation() {
        return operation;
    }

    public String getField() {
        return field;
    }

    @Override
    public boolean evaluate(MetaInfo metaInfo){

        if (StringUtils.isEmpty(field)) {
            return false;
        }

        //反射 获取字段值
        Object fact = super.fieldData(metaInfo,field);

        if (fact == null) {
            if (Operation.IS_EMPTY == operation) {
                return true;
            } else {
                return false;
            }
        }


        switch (operation) {
            case IS_NOT_EMPTY:
                return true;
            case GT:
                if (fact instanceof BigDecimal) {
                    return (new BigDecimal(factors.get(0))).compareTo((BigDecimal) fact) < 0;
                } else if (fact instanceof Number) {
                    return (new BigDecimal(factors.get(0))).compareTo(BigDecimal.valueOf(((Number) fact).doubleValue())) < 0;
                } else {
                    return factors.get(0).compareTo(fact.toString()) < 0;
                }
            case LT:
                if (fact instanceof BigDecimal) {
                    return (new BigDecimal(factors.get(0))).compareTo((BigDecimal) fact) > 0;
                } else if (fact instanceof Number) {
                    return (new BigDecimal(factors.get(0))).compareTo(BigDecimal.valueOf(((Number) fact).doubleValue())) > 0;
                } else {
                    return factors.get(0).compareTo(fact.toString()) >0;
                }
            case EQ:
                if (fact instanceof BigDecimal) {
                    return (new BigDecimal(factors.get(0))).compareTo((BigDecimal) fact) == 0;
                } else if (fact instanceof Number) {
                    return (new BigDecimal(factors.get(0))).compareTo(BigDecimal.valueOf(((Number) fact).doubleValue())) == 0;
                } else {
                    return factors.get(0).compareTo(fact.toString()) == 0;
                }
            case NEQ:
                if (fact instanceof BigDecimal) {
                    return (new BigDecimal(factors.get(0))).compareTo((BigDecimal) fact) != 0;
                } else if (fact instanceof Number) {
                    return (new BigDecimal(factors.get(0))).compareTo(BigDecimal.valueOf(((Number) fact).doubleValue())) != 0;
                } else {
                    return factors.get(0).compareTo(fact.toString()) != 0;
                }
            case GE:
                if (fact instanceof BigDecimal) {
                    return (new BigDecimal(factors.get(0))).compareTo((BigDecimal) fact) <= 0;
                } else if (fact instanceof Number) {
                    return (new BigDecimal(factors.get(0))).compareTo(BigDecimal.valueOf(((Number) fact).doubleValue())) <= 0;
                } else {
                    return factors.get(0).compareTo(fact.toString()) <= 0;
                }
            case LE:
                if (fact instanceof BigDecimal) {
                    return (new BigDecimal(factors.get(0))).compareTo((BigDecimal) fact) >= 0;
                } else if (fact instanceof Number) {
                    return (new BigDecimal(factors.get(0))).compareTo(BigDecimal.valueOf(((Number) fact).doubleValue())) >= 0;
                } else {
                    return factors.get(0).compareTo(fact.toString()) >= 0;
                }
            case IN:
                return factors.contains(fact.toString());
            case NOT_IN:
                return !factors.contains(fact.toString());
            case LEFT_LIKE:
                return fact.toString().startsWith(factors.get(0));
            case RIGHT_LIKE:
                return fact.toString().endsWith(factors.get(0));
            default:
                return false;
        }

    }

}
